/////////////////////////
////designer:Dup
////description:this module is used to wirte test result to the sram

module	write_sram(
			//input
			clk_1m,
			rst_n,
			wr_sram_req,
			init_resp_req,
			sram_ack,
			
			status0,status1,status2,status3,
			status4,status5,status6,status7,
			//output
			sram_wr,
			sram_addr,
			sram_data,
			wr_sram_done,
			init_resp_done
	);
	
input clk_1m;
input rst_n;
input wr_sram_req;
input init_resp_req;
input sram_ack;
input [7:0] status0,status1,status2,status3,
	        status4,status5,status6,status7;
	  
output sram_wr;
output [12:0]sram_addr;
output [7:0] sram_data;
output wr_sram_done;
output init_resp_done;

parameter	HEAD0_ADDR	=	13'h1d00,	
			HEAD1_ADDR	=	13'h1d01,
			LENGTH_ADDR =   13'h1d02,
			Status0_addr	=	13'h1d03,	
			Status1_addr	=	13'h1d04,
			Status2_addr	=	13'h1d05,
			Status3_addr	=	13'h1d06,
			Status4_addr	=	13'h1d07,
			Status5_addr	=	13'h1d08,
			Status6_addr	=	13'h1d09,
			Status7_addr	=	13'h1d0a,
						
			IDEL	=	3'd0,
			HEAD0	=	3'd1,
			HEAD1	=	3'd2,
			LENGTH  =   3'd3,
			STATUS	=	3'd4,
			DONE	=	3'd5;	
			

			
reg	[12:0]	sram_addr_reg;			
reg			sram_wr_reg,
			wr_sram_done,
			init_resp_done;
reg	[7:0]	sram_data_reg;			
reg	[2:0]	state,
			nstate;	

reg			flag;
reg	[3:0]	cnt;			
assign	sram_addr	=	(wr_sram_req  || init_resp_req)	     ?	sram_addr_reg	:	13'h000;		
assign	sram_wr		=	(wr_sram_req  || init_resp_req)		 ?	sram_wr_reg		:	1'b0;
assign	sram_data	=	(wr_sram_req  || init_resp_req)		 ?	sram_data_reg	:	8'h0;	


always@(posedge	clk_1m)	
	if(!rst_n)
		state	<=	IDEL;
	else	if(wr_sram_req == 1'b0 && init_resp_req == 1'b0 )
		state	<=	IDEL;
	else
		state	<=	nstate;
		
		
always@(*)
	if(!rst_n)
		nstate	=	IDEL;
	else	if(wr_sram_req == 1'b0 && init_resp_req == 1'b0 )
		nstate	=	IDEL;
	else case(state)
		IDEL   : nstate = HEAD0;
		HEAD0  : nstate = sram_ack ? HEAD1  : HEAD0;
		HEAD1  : nstate = sram_ack ? LENGTH : HEAD1;
		LENGTH : nstate = sram_ack ? STATUS : LENGTH;
		STATUS : nstate = ((cnt == 4'd8) && sram_ack)?DONE:STATUS;
		DONE   : nstate = DONE;
		default: nstate = IDEL;
		endcase	
		
always@(posedge	clk_1m)
	if(!rst_n)
		begin
		    sram_addr_reg	<=	13'h0;
			sram_wr_reg		<=	1'b0;
		 	sram_data_reg	<=	8'h0;
			wr_sram_done	<=	1'b0;
			init_resp_done  <=  1'b0;
			cnt				<=	4'd0;
			flag			<=	1'b0;
		end
	else
		if(wr_sram_req == 1'b0 && init_resp_req == 1'b0)
		begin
		    sram_addr_reg	<=	13'h0;
			sram_wr_reg		<=	1'b0;
		    sram_data_reg	<=	8'h0;
			wr_sram_done	<=	1'b0;
			init_resp_done  <=  1'b0;			
			cnt				<=	4'd0;
			flag			<=	1'b0;
		end
		
	else
		case(state)
		IDEL:begin
			sram_addr_reg	<=	13'h0;
			sram_wr_reg		<=	1'b0;
			sram_data_reg	<=	8'h0;
			wr_sram_done	<=	1'b0;
			init_resp_done  <=  1'b0;
			cnt				<=	4'd0;
			flag			<=	1'b0;
		end
		HEAD0:begin
			flag		<=	1'b1;
			sram_wr_reg	<=	1'b1;
			sram_addr_reg	<=	HEAD0_ADDR;
			if(init_resp_req)
				sram_data_reg	<=	8'h20;
			if(wr_sram_req)
				sram_data_reg	<=	8'h21;
			if(flag)
				sram_wr_reg	<=	1'b0;
			if(sram_ack)
				begin
					sram_wr_reg	<=	1'b0;
					flag		<=	1'b0;
					sram_addr_reg	<=	HEAD1_ADDR;
				end
		end
		HEAD1:begin
			flag		<=	1'b1;
			sram_wr_reg	<=	1'b1;
			sram_data_reg	<=	8'h00;
			if(flag)
				sram_wr_reg	<=	1'b0;
			if(sram_ack)
				begin
					sram_wr_reg	<=	1'b0;
					flag		<=	1'b0;	
				sram_addr_reg	<=	LENGTH_ADDR;					
				end
		end
		LENGTH:begin
			flag		    <=	1'b1;
			sram_wr_reg  	<=	1'b1;
			sram_data_reg	<=	8'd08;
			if(flag)
				sram_wr_reg	<=	1'b0;
			if(sram_ack)
				begin
					sram_wr_reg	<=	1'b0;
					flag		<=	1'b0;
				end
		end
		STATUS:begin
			     flag	<=	1'b1;
			sram_wr_reg	<=	1'b1;
			case(cnt)
			4'd0:begin
				sram_addr_reg	<=	Status0_addr;
				if(wr_sram_req)				
					sram_data_reg	<=	status0;
				if(init_resp_req)
					sram_data_reg	<=	8'h00;
			end
			4'd1:begin
				sram_addr_reg	<=	Status1_addr;
				if(wr_sram_req)				
					sram_data_reg	<=	status1;
				if(init_resp_req)
					sram_data_reg	<=	8'h01;
			end
			4'd2:begin
				sram_addr_reg	<=	Status2_addr;
				if(wr_sram_req)				
					sram_data_reg	<=	status2;
				if(init_resp_req)
					sram_data_reg	<=	8'h02;
			end
			4'd3:begin
				sram_addr_reg	<=	Status3_addr;
				if(wr_sram_req)				
					sram_data_reg	<=	status3;
				if(init_resp_req)
					sram_data_reg	<=	8'h03;
			end
			4'd4:begin
				sram_addr_reg	<=	Status4_addr;
				if(wr_sram_req)				
					sram_data_reg	<=	status4;
				if(init_resp_req)
					sram_data_reg	<=	8'h04;
			end
			4'd5:begin
				sram_addr_reg	<=	Status5_addr;
				if(wr_sram_req)				
					sram_data_reg	<=	status5;
				if(init_resp_req)
					sram_data_reg	<=	8'h05;
			end
			4'd6:begin
				sram_addr_reg	<=	Status6_addr;
				if(wr_sram_req)				
					sram_data_reg	<=	status6;
				if(init_resp_req)
					sram_data_reg	<=	8'h06;
			end
			4'd7:begin
				sram_addr_reg	<=	Status7_addr;
				if(wr_sram_req)				
					sram_data_reg	<=	status7;
				if(init_resp_req)
					sram_data_reg	<=	8'h07;
			end		
		
			default:	begin
			end

			endcase
			
			if(flag)
				sram_wr_reg	<=	1'b0;
			if(sram_ack)			
				begin
				sram_wr_reg	<=	1'b0;
					cnt		<=	cnt	+1'b1;
					flag	<=	1'b0;
				end
		end
		DONE:begin
			if(wr_sram_req)
				wr_sram_done	<=	1'b1;
			else 
				wr_sram_done    <=  1'b0;
			if(init_resp_req)
				init_resp_done  <=  1'b1;
			else 
				init_resp_done  <=  1'b0;
					cnt		<=	4'd0;
			sram_wr_reg		<=	1'b0;
			
			end
		default:begin
			wr_sram_done	<=	1'b1;
			init_resp_done  <=  1'b1;
			       cnt      <=	4'd0;
			sram_data_reg	<=	8'h0;
			sram_wr_reg		<=	1'b0;
			flag			<=	1'b0;			
			end
			
		endcase
		
endmodule


		

		
		
